package com.gosling.cloudspace.common.constants;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Random;

@Slf4j
public class StateUtils {
    private static Map<String, Map<String, String[]>> ACP_CODE = new LinkedHashMap<>();
    private static String[] ACP_CODE_ARRAY = {"success", "other"};
    private static String[] ACP_SUCCESS_KEY = {"00", "A6"};
    private static String[] ACP_OTHER_KEY = {"01", "02", "03", "04", "05", "06", "10", "11", "12", "13", "14", "30", "31", "32", "33", "34", "35", "36",
            "37", "38", "39", "40", "41", "42", "43", "44", "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", "70", "71", "72", "73",
            "74", "75", "76", "77", "78", "79", "80", "81", "82", "83", "85", "86", "87", "88", "98", "99"};

    static {
        initAcpCode();
    }

    public static void initAcpCode() {
        Map<String, String[]> acpSuccessCode = new HashMap<>(16);
        acpSuccessCode.put("00", new String[]{"00", "成功"});
        acpSuccessCode.put("A6", new String[]{"A6", "有缺陷的成功"});
        Map<String, String[]> acpOtherCode = new HashMap<>(16);
        acpOtherCode.put("01", new String[]{"01", "交易失败。详情请咨询 95516"});
        acpOtherCode.put("02", new String[]{"02", "系统未开放或暂时关闭，请稍后再试"});
        acpOtherCode.put("03", new String[]{"03", "交易通讯超时，请发起查询交易"});
        acpOtherCode.put("04", new String[]{"04", "交易状态未明，请查询对账结果"});
        acpOtherCode.put("05", new String[]{"05", "交易已受理，请稍后查询交易结果"});
        acpOtherCode.put("06", new String[]{"06", "系统繁忙，请稍后再试"});
        acpOtherCode.put("10", new String[]{"10", "报文格式错误"});
        acpOtherCode.put("11", new String[]{"11", "验证签名失败"});
        acpOtherCode.put("12", new String[]{"12", "重复交易"});
        acpOtherCode.put("13", new String[]{"13", "报文交易要素缺失"});
        acpOtherCode.put("14", new String[]{"14", "批量文件格式错误"});
        acpOtherCode.put("30", new String[]{"30", "交易未通过，请尝试使用其他银联卡支付或联系 95516"});
        acpOtherCode.put("31", new String[]{"31", "商户状态不正确"});
        acpOtherCode.put("32", new String[]{"32", "无此交易权限"});
        acpOtherCode.put("33", new String[]{"33", "交易金额超限"});
        acpOtherCode.put("34", new String[]{"34", "查无此交易"});
        acpOtherCode.put("35", new String[]{"35", "原交易不存在或状态不正确"});
        acpOtherCode.put("36", new String[]{"36", "与原交易信息不符"});
        acpOtherCode.put("37", new String[]{"37", "已超过最大查询次数或操作过于频繁"});
        acpOtherCode.put("38", new String[]{"38", "银联风险受限"});
        acpOtherCode.put("39", new String[]{"39", "交易不在受理时间范围内"});
        acpOtherCode.put("40", new String[]{"40", "绑定关系检查失败"});
        acpOtherCode.put("41", new String[]{"41", "批量状态不正确，无法下载"});
        acpOtherCode.put("42", new String[]{"42", "扣款成功但交易超过规定支付时间"});
        acpOtherCode.put("43", new String[]{"43", "无此业务权限，详情请咨询 95516"});
        acpOtherCode.put("44", new String[]{"44", "输入号码错误或暂未开通此项业务，详情请咨询 95516"});
        acpOtherCode.put("60", new String[]{"60", "交易失败，详情请咨询您的发卡行"});
        acpOtherCode.put("61", new String[]{"61", "输入的卡号无效，请确认后输入"});
        acpOtherCode.put("62", new String[]{"62", "交易失败，发卡银行不支持该商户，请更换其他银行卡"});
        acpOtherCode.put("63", new String[]{"63", "卡状态不正确"});
        acpOtherCode.put("64", new String[]{"64", "卡上的余额不足"});
        acpOtherCode.put("65", new String[]{"65", "输入的密码、有效期或 CVN2 有误，交易失败"});
        acpOtherCode.put("66", new String[]{"66", "持卡人身份信息或手机号输入不正确，验证失败"});
        acpOtherCode.put("67", new String[]{"67", "密码输入次数超限"});
        acpOtherCode.put("68", new String[]{"68", "您的银行卡暂不支持该业务，请向您的银行或 95516 咨询"});
        acpOtherCode.put("69", new String[]{"69", "您的输入超时，交易失败"});
        acpOtherCode.put("70", new String[]{"70", "交易已跳转，等待持卡人输入"});
        acpOtherCode.put("71", new String[]{"71", "动态口令或短信验证码校验失败"});
        acpOtherCode.put("72", new String[]{"72", "您尚未在{}银行网点柜面或个人网银签约加办银联无卡支付业务，请去柜面或网银开通或拨打{}"});
        acpOtherCode.put("73", new String[]{"73", "支付卡已超过有效期"});
        acpOtherCode.put("74", new String[]{"74", "扣款成功，销账未知"});
        acpOtherCode.put("75", new String[]{"75", "扣款成功，销账失败"});
        acpOtherCode.put("76", new String[]{"76", "需要验密开通"});
        acpOtherCode.put("77", new String[]{"77", "银行卡未开通认证支付"});
        acpOtherCode.put("78", new String[]{"78", "发卡行交易权限受限，详情请咨询您的发卡行"});
        acpOtherCode.put("79", new String[]{"79", "此卡可用，但发卡行暂不支持短信验证"});
        acpOtherCode.put("80", new String[]{"80", "交易失败，Token 已过期"});
        acpOtherCode.put("81", new String[]{"81", "月累计交易笔数(金额)超限"});
        acpOtherCode.put("82", new String[]{"82", "需要校验密码"});
        acpOtherCode.put("83", new String[]{"83", "发卡行（渠道）处理中"});
        acpOtherCode.put("85", new String[]{"85", "交易失败，营销规则不满足"});
        acpOtherCode.put("86", new String[]{"86", "二维码状态错误"});
        acpOtherCode.put("87", new String[]{"87", "支付次数超限"});
        acpOtherCode.put("88", new String[]{"88", "无此二维码"});
        acpOtherCode.put("98", new String[]{"98", "文件不存在"});
        acpOtherCode.put("SYSTEMERROR", new String[]{"SYSTEMERROR", "接口返回错误"});
        acpOtherCode.put("PARAM_ERROR", new String[]{"PARAM_ERROR", "参数错误"});
        acpOtherCode.put("99", new String[]{"99", "通用错误"});
        ACP_CODE.put("success", acpSuccessCode);
        ACP_CODE.put("other", acpOtherCode);
    }

    public static String getAcpStatus() {
        int random = getRandom(ACP_CODE_ARRAY.length);
        return ACP_CODE_ARRAY[random];
    }

    public static String[] getAcpRespCode(String status) {
        Map<String, String[]> acpCode = ACP_CODE.get(status);
        int key;
        String[] res = null;
        if("success".equals(status)) {
            key = getRandom(ACP_SUCCESS_KEY.length);
            res = acpCode.get(ACP_SUCCESS_KEY[key]);
        }else {
            key = getRandom(ACP_OTHER_KEY.length);
            res = acpCode.get(ACP_OTHER_KEY[key]);
        }
        return res;
    }

    public static void main(String[] args) {
        for(;;) {
            String status = getAcpStatus();
            System.out.println(JSON.toJSONString(getAcpRespCode(status)));
        }
    }

    private static int getRandom(int len) {
        Random random = new Random();
        return random.nextInt(len);
    }

}
